import { $api } from '@/cross/utils';
import {
  FileChange,
  LcFileChange,
  FileChangeWithSide,
} from '@/types/modules/editor/types/commit.type';

export interface GetFileChangesParams {
  projectId: string;
  path?: string;
  startTime?: number;
  endTime?: number;
  limit?: number;
  skip?: number;
  sortBy?: string;
  sortOrder?: 'asc' | 'desc';
  excludeDocFiles?: boolean; // 🆕 是否排除 .doc 文件
}

export interface GetFileChangesResponse {
  changes: LcFileChange[];
  total: number;
  hasMore: boolean;
}

export interface RecordFileChangeParams {
  projectId: string;
  path: string;
  action: 'add' | 'modify' | 'delete';
  content?: string; // 新增文件时需要完整内容
  diff?: string; // 修改文件时发送 diff
  previousContent?: string;
  contentHash?: string; // 用于验证内容完整性
  author?: string;
  message?: string;
}

export interface SyncFileChangesParams {
  projectId: string;
  changes: Array<{
    path: string;
    action: 'add' | 'modify' | 'delete';
    content?: string;
    previousContent?: string;
    timestamp: number;
    author?: string;
    version: number;
  }>;
}

export interface GetWorkingStatusParams {
  projectId: string;
  compareWith?: 'development' | 'release'; // 比对目标：开发版本或发布版本
}

export interface GetWorkingStatusResponse {
  success: boolean;
  hasChanges: boolean;
  changes: FileChangeWithSide<any>[];
  stats: {
    added: number;
    modified: number;
    deleted: number;
    total: number;
  };
}

/**
 * 历史记录 API 服务
 * 负责与后端版本控制服务对接
 */
export class HistoryApiService {
  private static instance: HistoryApiService;
  private baseUrl = '/version-control';

  static getInstance(): HistoryApiService {
    if (!HistoryApiService.instance) {
      HistoryApiService.instance = new HistoryApiService();
    }
    return HistoryApiService.instance;
  }

  /**
   * 获取文件的下一个版本号
   */
  async getNextVersion(projectId: string, path: string): Promise<number> {
    const response = await $api.get(`${this.baseUrl}/next-version/${projectId}`, { path });
    return response.nextVersion;
  }

  /**
   * 获取指定版本的文件内容
   */
  async getFileContent(projectId: string, path: string, version?: number): Promise<string> {
    const params: any = { path };
    if (version !== undefined) {
      params.version = version.toString();
    }

    const response = await $api.get(`${this.baseUrl}/file-content/${projectId}`, params);

    return response.content;
  }

  /**
   * 获取文件的最新内容
   */
  async getLatestFileContent(projectId: string, path: string): Promise<string> {
    return this.getFileContent(projectId, path);
  }

  /**
   * 获取文件变更历史
   */
  async getFileChanges(params: GetFileChangesParams): Promise<GetFileChangesResponse> {
    const { projectId, ...queryParams } = params;

    const response = await $api.get(`${this.baseUrl}/changes/${projectId}`, queryParams);

    return response;
  }

  /**
   * 记录单个文件变更
   */
  async recordFileChange(params: RecordFileChangeParams): Promise<LcFileChange> {
    const response = await $api.post(`${this.baseUrl}/changes`, params);
    return response.change;
  }

  /**
   * 批量同步文件变更
   */
  async syncFileChanges(params: SyncFileChangesParams): Promise<LcFileChange[]> {
    const response = await $api.post(`${this.baseUrl}/sync-changes`, params);
    return response.changes;
  }

  /**
   * 获取脏文件列表（基于最新变更记录）
   */
  async getDirtyFiles(projectId: string): Promise<Map<string, any>> {
    // 获取最近的变更记录，用于判断脏文件状态
    const response = await this.getFileChanges({
      projectId,
      limit: 100,
      sortBy: 'timestamp',
      sortOrder: 'desc',
    });

    // 构建脏文件映射
    const dirtyFiles = new Map();
    const recentChanges = response.changes.slice(0, 50); // 只考虑最近50个变更

    recentChanges.forEach((change) => {
      if (!dirtyFiles.has(change.path)) {
        dirtyFiles.set(change.path, {
          type: change.action,
          timestamp: change.timestamp,
          userId: change.author || 'unknown',
          lastEditMode: change.meta?.type === 'user' ? 'vi' : 'code',
        });
      }
    });

    return dirtyFiles;
  }

  /**
   * 获取工作区状态（类似 git status）
   */
  async getWorkingStatus(params: GetWorkingStatusParams): Promise<GetWorkingStatusResponse> {
    const { projectId, compareWith = 'development' } = params;

    const response = await $api.get(`${this.baseUrl}/status/${projectId}`, {
      compareWith,
    });

    return response;
  }

  /**
   * 迁移本地历史记录到后端
   */
  async migrateLocalHistory(
    projectId: string,
    localChanges: FileChange<any>[],
    onProgress?: (current: number, total: number) => void,
  ): Promise<{ success: number; failed: number; errors: string[] }> {
    const batchSize = 10;
    const batches = [];
    const errors: string[] = [];
    let successCount = 0;
    let failedCount = 0;

    // 分批处理
    for (let i = 0; i < localChanges.length; i += batchSize) {
      batches.push(localChanges.slice(i, i + batchSize));
    }

    console.log(
      `[HistoryApiService] 开始迁移 ${localChanges.length} 条历史记录，分 ${batches.length} 批处理`,
    );

    for (let i = 0; i < batches.length; i++) {
      const batch = batches[i];

      try {
        const changes = batch.map((change) => ({
          path: change.path,
          action: change.action,
          content: change.diff?.after ? JSON.stringify(change.diff.after) : undefined,
          previousContent: change.diff?.before ? JSON.stringify(change.diff.before) : undefined,
          timestamp: change.timestamp,
          author: change.author,
          version: change.version,
        }));

        await this.syncFileChanges({ projectId, changes });
        successCount += batch.length;

        console.log(
          `[HistoryApiService] 批次 ${i + 1}/${batches.length} 迁移成功，${batch.length} 条记录`,
        );
      } catch (error) {
        failedCount += batch.length;
        const errorMsg = `批次 ${i + 1} 迁移失败: ${error.message}`;
        errors.push(errorMsg);
        console.error(`[HistoryApiService] ${errorMsg}`, error);
      }

      // 报告进度
      if (onProgress) {
        onProgress((i + 1) * batchSize, localChanges.length);
      }

      // 避免请求过于频繁
      if (i < batches.length - 1) {
        await new Promise((resolve) => setTimeout(resolve, 100));
      }
    }

    console.log(`[HistoryApiService] 迁移完成: 成功 ${successCount}, 失败 ${failedCount}`);

    return {
      success: successCount,
      failed: failedCount,
      errors,
    };
  }
}
